import logging
import random
from time import sleep

import httpx as hx

import config as c


# @SingleInstance
class SingleInstance(object):
    def __init__(self, cls):
        self.__cls = cls
        self.__instance = {}

    def __call__(self):
        if self.__cls not in self.__instance:
            self.__instance[self.__cls] = self.__cls()
        return self.__instance[self.__cls]


class REQUEST:
    proxy = {
        "https://": "",
        "http://": ""
    }
    headers = {
        "User-Agent": c.HEADERS_LIST[0],
        "Accept": "*/*",
        "Accept-Encoding": "gzip, deflate, br, zstd",
        "Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
        "Sec-Ch-Ua": '"Microsoft Edge";v="123", "Not:A-Brand";v="8", "Chromium";v="123"',
        "Referer": "",
    }

    def __init__(self):
        self.getProxy()
        self.sleep_time = 0.0
        self.ctx = hx.Client(http2=True, verify=False, timeout=None)

    def __del__(self):
        self.ctx.close()

    def getProxy(self):
        # htp_j = hx.get("http://127.0.0.1:5010/get", allow_redirects=True).json()
        # htps_j = hx.get("http://127.0.0.1:5010/get/?type=https", allow_redirects=True).json()
        htp_j = hx.get("http://demo.spiderpy.cn/get", allow_redirects=True, timeout=None).json()
        htps_j = hx.get("http://demo.spiderpy.cn/get/?type=https", allow_redirects=True, timeout=None).json()
        logging.info(f"获取到新代理：{htp_j.get('proxy')}|{htps_j.get('proxy')}")
        ps_str = htps_j.get("proxy")
        p_str = htp_j.get("proxy")
        if ps_str == None:
            logging.warning("检测到HTTPS代理错误，请稍后重试")
            ps_str = p_str
        if p_str == None:
            logging.warning("检测到HTTP代理错误，请稍后重试")
            p_str = ps_str
        self.proxy['https://'] = "https://" + ps_str
        self.proxy['http://'] = "http://" + p_str

    def get(self, url) -> hx.Response:
        self.headers["Referer"] = url.split('com')[0] + 'com'
        retryCnt = 5
        while retryCnt > 0:
            try:
                # time.sleep(random.uniform(1, 2))
                sleep(self.sleep_time)
                resp = self.ctx.get(url, headers=self.headers)
                if resp.status_code == 403:
                    raise Exception()
                if resp.status_code == 429:
                    self.sleep_time = random.uniform(1, 2)
                return resp
            except Exception as e:
                logging.warning(f"无效代理, 重试{retryCnt}次: ")
                retryCnt -= 1
                if retryCnt < 1:
                    retryCnt = 5
                    self.getProxy()
        return None
